home *** CD-ROM | disk | FTP | other *** search
/ Giga Games 1 / Giga Games.iso / net / hack / 3_1_3 / sys / amiga / winmenu.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-05-24  |  19.6 KB  |  862 lines

  1. /*    SCCS Id: @(#)winmenu.c    3.1    93/04/02 */
  2. /* Copyright (c) Gregg Wonderly, Naperville, Illinois,  1991,1992,1993. */
  3. /* NetHack may be freely redistributed.  See license for details. */
  4.  
  5. #include "amiga:windefs.h"
  6. #include "amiga:winext.h"
  7. #include "amiga:winproto.h"
  8.  
  9. /* Start building the text for a menu */
  10. void
  11. amii_start_menu(window)
  12.     register winid window;
  13. {
  14.     register int i;
  15.     register struct amii_WinDesc *cw;
  16.  
  17.     if(window == WIN_ERR || (cw = amii_wins[window]) == NULL || cw->type != NHW_MENU)
  18.     panic(winpanicstr,window, "start_menu");
  19.  
  20.     amii_clear_nhwindow(window);
  21.     if( window == WIN_INVEN && cw->win != NULL )
  22.     {
  23.     if( cw->data && ( cw->type == NHW_MESSAGE ||
  24.         cw->type == NHW_MENU || cw->type == NHW_TEXT ) )
  25.     {
  26.         for( i = 0; i < cw->maxrow; ++i )
  27.         {
  28.         if( cw->data[ i ] )
  29.             free( cw->data[ i ] );
  30.         }
  31.         free( cw->data );
  32.         cw->data = NULL;
  33.     }
  34.  
  35.     if( cw->canresp ) free( cw->canresp );
  36.     cw->canresp = NULL;
  37.  
  38.     if( cw->morestr ) free( cw->morestr );
  39.     cw->morestr = NULL;
  40.     if( alwaysinvent )
  41.         cw->wasup = 1;
  42.     }
  43.     if( cw->resp )
  44.     *cw->resp = 0;
  45.     cw->maxrow = cw->maxcol = 0;
  46.     return;
  47. }
  48.  
  49. /* Add a string to a menu */
  50. void
  51. amii_add_menu(window,ch,attr,str)
  52.     register winid window;
  53.     register char ch;
  54.     register int attr;
  55.     register const char *str;
  56. {
  57.     register struct amii_WinDesc *cw;
  58.     char tmpbuf[2];
  59.  
  60.     if(str == NULL)return;
  61.  
  62.     if(window == WIN_ERR || (cw = amii_wins[window]) == NULL || cw->type != NHW_MENU)
  63.     panic(winpanicstr,window, "add_menu");
  64.  
  65.     /* this should translate fonts if a title line */
  66.     amii_putstr(window, attr, str);
  67.  
  68.     if( !cw->resp )
  69.     panic("No response buffer in add_menu()");
  70.  
  71.     if( !cw->data )
  72.     panic("No data buffer in add_menu()");
  73.  
  74.     if(ch != '\0')
  75.     {
  76.     tmpbuf[0]=ch;
  77.     tmpbuf[1]=0;
  78.     Strcat(cw->resp, tmpbuf);
  79.     cw->data[ cw->cury - 1 ][ SEL_ITEM ] = 1;
  80.     }
  81.     else
  82.     {
  83.     /* Use something as a place holder.  ^A is probably okay */
  84.  
  85.     tmpbuf[0]=1;
  86.     tmpbuf[1]=0;
  87.     Strcat(cw->resp, tmpbuf);
  88.     cw->data[ cw->cury - 1 ][ SEL_ITEM ] = 0;
  89.     }
  90. }
  91.  
  92. /* Done building a menu. */
  93.  
  94. void
  95. amii_end_menu(window,cancel,str,morestr)
  96.     register winid window;
  97.     register char cancel;
  98.     register const char *str;
  99.     register const char *morestr;
  100. {
  101.     register struct amii_WinDesc *cw;
  102.  
  103.     if(window == WIN_ERR || (cw=amii_wins[window]) == NULL || cw->type != NHW_MENU
  104.       || cw->canresp)
  105.     panic(winpanicstr,window, "end_menu");
  106.  
  107.     if(str)
  108.     {
  109.     cw->canresp = (char*) alloc(strlen(str)+2);
  110.     cw->canresp[0]=cancel;
  111.     Strcpy(&cw->canresp[1],str);
  112.  
  113.     if( !cw->resp )
  114.         panic("No response buffer in end_menu()");
  115.  
  116.     strncat(cw->resp, str, 1);
  117.     }
  118.  
  119.     if(morestr)
  120.     {
  121.     cw->morestr =(char *) alloc(strlen(morestr)+1);
  122.     Strcpy(cw->morestr, morestr);
  123.     }
  124. }
  125.  
  126. /* Select something from the menu. */
  127.  
  128. char
  129. amii_select_menu(window)
  130.     register winid window;
  131. {
  132.     register struct amii_WinDesc *cw;
  133.  
  134.     if( window == WIN_ERR || ( cw=amii_wins[window] ) == NULL ||
  135.       cw->type != NHW_MENU )
  136.     panic(winpanicstr,window, "select_menu");
  137.  
  138.     morc = 0;                       /* very ugly global variable */
  139.     amii_display_nhwindow(window,TRUE); /* this waits for input */
  140.  
  141.     /* This would allow the inventory window to stay open. */
  142.     if( !alwaysinvent || window != WIN_INVEN )
  143.     dismiss_nhwindow(window);       /* Now tear it down */
  144.     return morc;
  145. }
  146.  
  147. void
  148. DoMenuScroll( win, blocking )
  149.     int win, blocking;
  150. {
  151.     register struct Window *w;
  152.     register struct NewWindow *nw;
  153.     struct PropInfo *pip;
  154.     register struct amii_WinDesc *cw;
  155.     struct IntuiMessage *imsg;
  156.     struct Gadget *gd;
  157.     register int wheight, xsize, ysize, aredone = 0;
  158.     register int txwd, txh;
  159.     long mics, secs, class, code;
  160.     long oldmics = 0, oldsecs = 0;
  161.     int aidx, oidx, topidx, hidden;
  162.     int totalvis, i;
  163.     char *t;
  164.     SHORT mx, my;
  165.     static char title[ 100 ];
  166.     int dosize = 1;
  167.     struct Screen *scrn = HackScreen;
  168.  
  169.     if( win == WIN_ERR || ( cw = amii_wins[ win ] ) == NULL )
  170.     panic(winpanicstr,win,"DoMenuScroll");
  171.  
  172.     /*  Initial guess at window sizing values */
  173.     txwd = txwidth;
  174.     txh = txheight; /* interline space */
  175.  
  176.     /* Check to see if we should open the window, should need to for
  177.      * TEXT and MENU but not MESSAGE.
  178.      */
  179.  
  180.     totalvis = cw->maxrow;
  181.     w = cw->win;
  182.     topidx = 0;
  183.  
  184.     if( w == NULL )
  185.     {
  186.  
  187. #ifdef  INTUI_NEW_LOOK
  188.     if( IntuitionBase->LibNode.lib_Version >= 37 )
  189.     {
  190.         PropScroll.Flags |= PROPNEWLOOK;
  191.     }
  192. #endif
  193.     nw = (void *)DupNewWindow( (void *)(&new_wins[ cw->type ].newwin) );
  194.     if( !alwaysinvent || win != WIN_INVEN )
  195.     {
  196.         xsize = scrn->WBorLeft + scrn->WBorRight + MenuScroll.Width + 1 +
  197.                 (txwd * cw->maxcol);
  198.  
  199.         if( xsize > amiIDisplay->xpix )
  200.         xsize = amiIDisplay->xpix;
  201.  
  202.         /* If next row not off window, use it, else use the bottom */
  203.  
  204.         ysize = ( txh * cw->maxrow ) +                /* The text space */
  205.             HackScreen->WBorTop + txheight + 1 +  /* Top border */
  206.             HackScreen->WBorBottom + 3;           /* The bottom border */
  207.         if( ysize > amiIDisplay->ypix )
  208.         ysize = amiIDisplay->ypix;
  209.  
  210.         /* Adjust the size of the menu scroll gadget */
  211.  
  212.         nw->TopEdge = 0;
  213.         if( cw->type == NHW_TEXT && ysize < amiIDisplay->ypix )
  214.         nw->TopEdge += ( amiIDisplay->ypix - ysize ) / 2;
  215.         nw->LeftEdge = amiIDisplay->xpix - xsize;
  216.         if( cw->type == NHW_TEXT && xsize < amiIDisplay->xpix )
  217.         nw->LeftEdge -= ( amiIDisplay->xpix - xsize ) / 2;
  218.     }
  219.     else
  220.     {
  221.         struct Window *mw = amii_wins[ WIN_MAP ]->win;
  222.         struct Window *sw = amii_wins[ WIN_STATUS ]->win;
  223.  
  224. #ifndef    VIEWWINDOW
  225.         xsize = scrn->WBorLeft + scrn->WBorRight + MenuScroll.Width + 1 +
  226.                 (txwd * cw->maxcol);
  227. #else
  228.         xsize = mw->Width;
  229. #endif
  230.         if( xsize > amiIDisplay->xpix )
  231.         xsize = amiIDisplay->xpix;
  232.  
  233.         /* If next row not off window, use it, else use the bottom */
  234.  
  235.         ysize = sw->TopEdge - (mw->TopEdge + mw->Height) - 1;
  236.         if( ysize > amiIDisplay->ypix )
  237.         ysize = amiIDisplay->ypix;
  238.  
  239.         /* Adjust the size of the menu scroll gadget */
  240.  
  241.         nw->TopEdge = mw->TopEdge + mw->Height;
  242.         nw->LeftEdge = 0;
  243.     }
  244.     cw->newwin = (void *)nw;
  245.     if( nw == NULL )
  246.         panic("No NewWindow Allocated" );
  247.  
  248.     nw->Screen = HackScreen;
  249.  
  250.     if( win == WIN_INVEN )
  251.     {
  252.         sprintf( title, "%s the %s's Inventory", plname, pl_character );
  253.         nw->Title = title;
  254.         if( lastinvent.MaxX != 0 )
  255.         {
  256.         nw->LeftEdge = lastinvent.MinX;
  257.         nw->TopEdge = lastinvent.MinY;
  258.         nw->Width = lastinvent.MaxX;
  259.         nw->Height = lastinvent.MaxY;
  260.         }
  261.     }
  262.     else if( cw->morestr )
  263.         nw->Title = cw->morestr;
  264.  
  265.     /* Adjust the window coordinates and size now that we know
  266.      * how many items are to be displayed.
  267.      */
  268.  
  269.     if( ( xsize > amiIDisplay->xpix - nw->LeftEdge ) &&
  270.         ( xsize < amiIDisplay->xpix ) )
  271.     {
  272.         nw->LeftEdge = amiIDisplay->xpix - xsize;
  273.         nw->Width = xsize;
  274.     }
  275.     else
  276.     {
  277.         nw->Width = min( xsize, amiIDisplay->xpix - nw->LeftEdge );
  278.     }
  279.     nw->Height = min( ysize, amiIDisplay->ypix - nw->TopEdge );
  280.  
  281.     /* Now, open the window */
  282.     w = cw->win = OpenShWindow( (void *)nw );
  283.  
  284.     if( w == NULL )
  285.     {
  286.         char buf[ 130 ];
  287.  
  288.         sprintf( buf, "No Window Opened For Menu (%d,%d,%d-%d,%d-%d)",
  289.         nw->LeftEdge, nw->TopEdge, nw->Width, amiIDisplay->xpix,
  290.         nw->Height, amiIDisplay->ypix );
  291.         panic( buf );
  292.     }
  293.  
  294. #ifdef HACKFONT
  295.     if( TextsFont )
  296.         SetFont(w->RPort, TextsFont );
  297.     else if( HackFont )
  298.         SetFont(w->RPort, HackFont );
  299. #endif
  300.     txwd = w->RPort->TxWidth;
  301.     txh = w->RPort->TxHeight; /* interline space */
  302.  
  303.     /* subtract 2 to account for spacing away from border (1 on each side) */
  304.     wheight = ( w->Height - w->BorderTop - w->BorderBottom - 2 ) / txh;
  305.     cw->cols = ( w->Width - w->BorderLeft - w->BorderRight - 2 ) / txwd;
  306.     }
  307.     else
  308.     {
  309.     txwd = w->RPort->TxWidth;
  310.     txh = w->RPort->TxHeight; /* interline space */
  311.  
  312.     /* subtract 2 to account for spacing away from border (1 on each side) */
  313.     wheight = ( w->Height - w->BorderTop - w->BorderBottom - 2 ) / txh;
  314.     cw->cols = ( w->Width - w->BorderLeft - w->BorderRight - 2 ) / txwd;
  315.  
  316.     if( win == WIN_MESSAGE )
  317.     {
  318.         for( totalvis = i = 0; i < cw->maxrow; ++i )
  319.         {
  320.         if( cw->data[i] && cw->data[i][1] != 0xff )
  321.             ++totalvis;
  322.         }
  323.     }
  324.     for( gd = w->FirstGadget; gd && gd->GadgetID != 1; )
  325.         gd = gd->NextGadget;
  326.  
  327.     if( gd )
  328.     {
  329.         pip = (struct PropInfo *)gd->SpecialInfo;
  330.         hidden = max( cw->maxrow - wheight, 0 );
  331.         topidx = (((ULONG)hidden * pip->VertPot) + (MAXPOT/2)) >> 16;
  332.     }
  333.     }
  334.  
  335.     /* Find the scroll gadget */
  336.     for( gd = w->FirstGadget; gd && gd->GadgetID != 1; gd = gd->NextGadget )
  337.     continue;
  338.  
  339.     if( !gd ) panic("Can't find scroll gadget" );
  340.  
  341.     morc = 0;
  342.     oidx = -1;
  343.  
  344.     DisplayData( win, topidx, -1 );
  345.     WindowToFront( w );
  346.  
  347.     /* Make the prop gadget the right size and place */
  348.  
  349.     SetPropInfo( w, gd, wheight, totalvis, topidx );
  350.     oldsecs = oldmics = 0;
  351.  
  352.     /* If window already up, don't stop to process events */
  353.     if( cw->wasup )
  354.     {
  355.         aredone = 1;
  356.         cw->wasup = 0;
  357.     }
  358.  
  359.     while( !aredone )
  360.     {
  361.     /* Process window messages */
  362.  
  363.     WaitPort( w->UserPort );
  364.     while( imsg = (struct IntuiMessage * ) GetMsg( w->UserPort ) )
  365.     {
  366.         class = imsg->Class;
  367.         code = imsg->Code;
  368.         mics = imsg->Micros;
  369.         secs = imsg->Seconds;
  370.         gd = (struct Gadget *) imsg->IAddress;
  371.         mx = imsg->MouseX;
  372.         my = imsg->MouseY;
  373.  
  374.         /* Only do our window or VANILLAKEY from other windows */
  375.  
  376.         if( imsg->IDCMPWindow != w && class != VANILLAKEY &&
  377.                             class != RAWKEY )
  378.         {
  379.         ReplyMsg( (struct Message *) imsg );
  380.         continue;
  381.         }
  382.  
  383.         /* Do DeadKeyConvert() stuff if RAWKEY... */
  384.         if( class == RAWKEY )
  385.         {
  386.         class = VANILLAKEY;
  387.         code = ConvertKey( imsg );
  388.         }
  389.         ReplyMsg( (struct Message *) imsg );
  390.  
  391.         switch( class )
  392.         {
  393.         case NEWSIZE:
  394.             /* Ignore every other newsize, no action needed */
  395.  
  396.             if( !dosize )
  397.             {
  398.             dosize = 1;
  399.             break;
  400.             }
  401.  
  402.             if( win == WIN_INVEN )
  403.             {
  404.             lastinvent.MinX = w->LeftEdge;
  405.             lastinvent.MinY = w->TopEdge;
  406.             lastinvent.MaxX = w->Width;
  407.             lastinvent.MaxY = w->Height;
  408.             }
  409.             else if( win == WIN_MESSAGE )
  410.             {
  411.             lastmsg.MinX = w->LeftEdge;
  412.             lastmsg.MinY = w->TopEdge;
  413.             lastmsg.MaxX = w->Width;
  414.             lastmsg.MaxY = w->Height;
  415.             }
  416.  
  417.             /* Find the gadget */
  418.  
  419.             for( gd = w->FirstGadget; gd && gd->GadgetID != 1; )
  420.             gd = gd->NextGadget;
  421.  
  422.             if( !gd )
  423.             panic("Can't find scroll gadget" );
  424.  
  425.             wheight = ( w->Height - w->BorderTop -
  426.                         w->BorderBottom - 2) / txh;
  427.             cw->cols = ( w->Width -
  428.                 w->BorderLeft - w->BorderRight ) / txwd;
  429.             if( wheight < 2 )
  430.             wheight = 2;
  431.  
  432.             /* Make the prop gadget the right size and place */
  433.  
  434.             DisplayData( win, topidx, oidx );
  435.             SetPropInfo( w, gd, wheight, totalvis, topidx );
  436.  
  437.             /* Force the window to a text line boundry <= to
  438.              * what the user dragged it to.  This eliminates
  439.              * having to clean things up on the bottom edge.
  440.              */
  441.  
  442.             SizeWindow( w, 0, ( wheight * txh) +
  443.                 w->BorderTop + w->BorderBottom + 2 - w->Height );
  444.  
  445.             /* Don't do next NEWSIZE, we caused it */
  446.             dosize = 0;
  447.             oldsecs = oldmics = 0;
  448.             break;
  449.  
  450.         case VANILLAKEY:
  451. #define CTRL(x)     ((x)-'@')
  452.             if( code == CTRL('D') || code == CTRL('U') )
  453.             {
  454.             int endcnt, i;
  455.  
  456.             for( gd = w->FirstGadget; gd && gd->GadgetID != 1; )
  457.                 gd = gd->NextGadget;
  458.  
  459.             if( !gd )
  460.                 panic("Can't find scroll gadget" );
  461.  
  462.             endcnt = wheight / 2;
  463.             if( endcnt == 0 )
  464.                 endcnt = 1;
  465.  
  466.             for( i = 0; i < endcnt; ++i )
  467.             {
  468.                 if( code == CTRL('D') )
  469.                 {
  470.                 if( topidx + wheight < cw->maxrow )
  471.                     ++topidx;
  472.                 else
  473.                     break;
  474.                 }
  475.                 else
  476.                 {
  477.                 if( topidx > 0 )
  478.                     --topidx;
  479.                 else
  480.                     break;
  481.                 }
  482.  
  483.                 /* Make prop gadget the right size and place */
  484.  
  485.                 DisplayData( win, topidx, oidx );
  486.                 SetPropInfo( w,gd, wheight, totalvis, topidx );
  487.             }
  488.             oldsecs = oldmics = 0;
  489.             }
  490.             else if( code == '\b' )
  491.             {
  492.             for( gd = w->FirstGadget; gd && gd->GadgetID != 1; )
  493.                 gd = gd->NextGadget;
  494.  
  495.             if( !gd )
  496.                 panic("Can't find scroll gadget" );
  497.  
  498.             if( topidx - wheight - 2 < 0 )
  499.             {
  500.                 topidx = 0;
  501.             }
  502.             else
  503.             {
  504.                 topidx -= wheight - 2;
  505.             }
  506.             DisplayData( win, topidx, oidx );
  507.             SetPropInfo( w, gd, wheight, totalvis, topidx );
  508.             oldsecs = oldmics = 0;
  509.             }
  510.             else if( code == ' ' )
  511.             {
  512.             for( gd = w->FirstGadget; gd && gd->GadgetID != 1; )
  513.                 gd = gd->NextGadget;
  514.  
  515.             if( !gd )
  516.                 panic("Can't find scroll gadget" );
  517.  
  518.             if( topidx + wheight >= cw->maxrow )
  519.             {
  520.                 morc = 0;
  521.                 aredone = 1;
  522.             }
  523.             else
  524.             {
  525.                 /*  If there are still lines to be seen */
  526.  
  527.                 if( cw->maxrow > topidx + wheight )
  528.                 {
  529.                 if( wheight > 2 )
  530.                     topidx += wheight - 2;
  531.                 else
  532.                     ++topidx;
  533.                 DisplayData( win, topidx, oidx );
  534.                 SetPropInfo( w, gd, wheight,
  535.                             totalvis, topidx );
  536.                 }
  537.                 oldsecs = oldmics = 0;
  538.             }
  539.             }
  540.             else if( code == '\n' || code == '\r' )
  541.             {
  542.             for( gd = w->FirstGadget; gd && gd->GadgetID != 1; )
  543.                 gd = gd->NextGadget;
  544.  
  545.             if( !gd )
  546.                 panic("Can't find scroll gadget" );
  547.  
  548.             /* If all line displayed, we are done */
  549.  
  550.             if( topidx + wheight >= cw->maxrow )
  551.             {
  552.                 morc = 0;
  553.                 aredone = 1;
  554.             }
  555.             else
  556.             {
  557.                 /*  If there are still lines to be seen */
  558.  
  559.                 if( cw->maxrow > topidx + 1 )
  560.                 {
  561.                 ++topidx;
  562.                 DisplayData( win, topidx, oidx );
  563.                 SetPropInfo( w, gd, wheight,
  564.                             totalvis, topidx );
  565.                 }
  566.                 oldsecs = oldmics = 0;
  567.             }
  568.             }
  569.             else if( cw->resp && index( cw->resp, code ) )
  570.             {
  571.             morc = code;
  572.             aredone = 1;
  573.             }
  574.             else if( code == '\33' || code == 'q' || code == 'Q' )
  575.             {
  576.             morc = '\33';
  577.             aredone = 1;
  578.             }
  579.             break;
  580.  
  581.         case CLOSEWINDOW:
  582.             if( win == WIN_INVEN )
  583.             {
  584.             lastinvent.MinX = w->LeftEdge;
  585.             lastinvent.MinY = w->TopEdge;
  586.             lastinvent.MaxX = w->Width;
  587.             lastinvent.MaxY = w->Height;
  588.             }
  589.             else if( win == WIN_MESSAGE )
  590.             {
  591.             lastmsg.MinX = w->LeftEdge;
  592.             lastmsg.MinY = w->TopEdge;
  593.             lastmsg.MaxX = w->Width;
  594.             lastmsg.MaxY = w->Height;
  595.             }
  596.             aredone = 1;
  597.             morc = '\33';
  598.             break;
  599.  
  600.         case GADGETUP:
  601.             if( win == WIN_MESSAGE )
  602.             aredone = 1;
  603.             for( gd = w->FirstGadget; gd && gd->GadgetID != 1; )
  604.             gd = gd->NextGadget;
  605.  
  606.             pip = (struct PropInfo *)gd->SpecialInfo;
  607.             hidden = max( cw->maxrow - wheight, 0 );
  608.             aidx = (((ULONG)hidden * pip->VertPot) + (MAXPOT/2)) >> 16;
  609.             if( aidx != topidx )
  610.             DisplayData( win, topidx = aidx, oidx );
  611.             break;
  612.  
  613.         case MOUSEMOVE:
  614.             for( gd = w->FirstGadget; gd && gd->GadgetID != 1; )
  615.             gd = gd->NextGadget;
  616.  
  617.             pip = (struct PropInfo *)gd->SpecialInfo;
  618.             hidden = max( cw->maxrow - wheight, 0 );
  619.             aidx = (((ULONG)hidden * pip->VertPot) + (MAXPOT/2)) >> 16;
  620.             if( aidx != topidx )
  621.             DisplayData( win, topidx = aidx, oidx );
  622.             break;
  623.  
  624.         case INACTIVEWINDOW:
  625.             if( win == WIN_MESSAGE || ( win == WIN_INVEN && alwaysinvent ) )
  626.             aredone = 1;
  627.             break;
  628.  
  629.         case MOUSEBUTTONS:
  630.             if( ( code == SELECTUP || code == SELECTDOWN ) &&
  631.                             cw->type == NHW_MENU )
  632.             {
  633.             /* Which one is the mouse pointing at? */
  634.  
  635.             aidx = ( ( my - w->BorderTop - 1 ) /
  636.                         w->RPort->TxHeight ) + topidx;
  637.  
  638.             /* If different lines, don't select double click */
  639.  
  640.             if( aidx != oidx )
  641.             {
  642.                 oldsecs = 0;
  643.                 oldmics = 0;
  644.             }
  645.  
  646.             /* If releasing, check for double click */
  647.  
  648.             if( code == SELECTUP )
  649.             {
  650.                 if( aidx == oidx )
  651.                 {
  652.                 if( DoubleClick( oldsecs,
  653.                             oldmics, secs, mics ) )
  654.                 {
  655.                     morc = cw->resp[ aidx ];
  656.                     aredone = 1;
  657.                 }
  658.                 oldsecs = secs;
  659.                 oldmics = mics;
  660.                 }
  661.             }
  662.             else if( aidx < cw->maxrow && code == SELECTDOWN )
  663.             {
  664.                 /* Remove old highlighting if visible */
  665.  
  666.                 if( oidx > topidx && oidx - topidx < wheight )
  667.                 {
  668.                 t = cw->data[ oidx ] + SOFF;
  669.                 amii_curs( win, 1, oidx - topidx  );
  670.                 SetDrMd( w->RPort, JAM2 );
  671.                 SetAPen( w->RPort, C_WHITE );
  672.                 SetBPen( w->RPort, C_BLACK );
  673.                 Text( w->RPort, t, strlen( t ) );
  674.                 oidx = -1;
  675.                 }
  676.  
  677.                 t = cw->data[ aidx ];
  678.                 if( t && t[ SEL_ITEM ] == 1 )
  679.                 {
  680.                 oidx = aidx;
  681.  
  682.                 amii_curs( win, 1, aidx - topidx );
  683.                 SetDrMd( w->RPort, JAM2 );
  684.                 SetAPen( w->RPort, C_BLUE );
  685.                 SetBPen( w->RPort, C_WHITE );
  686.                 t += SOFF;
  687.                 Text( w->RPort, t, strlen( t ) );
  688.                 }
  689.                 else
  690.                 {
  691.                 DisplayBeep( NULL );
  692.                 oldsecs = 0;
  693.                 oldmics = 0;
  694.                 }
  695.             }
  696.             }
  697.             else
  698.             {
  699.             DisplayBeep( NULL );
  700.             }
  701.             break;
  702.         }
  703.     }
  704.     }
  705.     /* Force a cursor reposition before next message output */
  706.     if( win == WIN_MESSAGE )
  707.     cw->curx = -1;
  708.  
  709. #if 0
  710.     if( WIN_MAP != WIN_ERR && amii_wins[ WIN_MAP ] )
  711.     ActivateWindow( amii_wins[ WIN_MAP ]->win );
  712. #endif
  713. }
  714.  
  715. ReDisplayData( win )
  716.     winid win;
  717. {
  718.     register struct amii_WinDesc *cw;
  719.     register struct Window *w;
  720.     register struct Gadget *gd;
  721.     unsigned long hidden, aidx, wheight;
  722.     struct PropInfo *pip;
  723.     
  724.     if( win == WIN_ERR || !(cw = amii_wins[win]) || !( w = cw->win ) )
  725.     return;
  726.  
  727.     for( gd = w->FirstGadget; gd && gd->GadgetID != 1; )
  728.     gd = gd->NextGadget;
  729.  
  730.     if( !gd )
  731.     return;
  732.  
  733.     wheight = ( w->Height - w->BorderTop -
  734.             w->BorderBottom - 2 ) / w->RPort->TxHeight;
  735.     pip = (struct PropInfo *)gd->SpecialInfo;
  736.     hidden = max( cw->maxrow - wheight, 0 );
  737.     aidx = (((ULONG)hidden * pip->VertPot) + (MAXPOT/2)) >> 16;
  738.     DisplayData( win, aidx, -1 );
  739. }
  740.  
  741. void
  742. DisplayData( win, start, where )
  743.     winid win;
  744.     int start;
  745.     int where;
  746. {
  747.     register char *t;
  748.     register struct amii_WinDesc *cw;
  749.     register struct Window *w;
  750.     register int i, idx, len, wheight;
  751.     int col = -1;
  752.  
  753.     if( win == WIN_ERR || !(cw = amii_wins[win]) || !( w = cw->win ) )
  754.     {
  755.     panic( winpanicstr, win, "No Window in DisplayData" );
  756.     }
  757.  
  758.     SetDrMd( w->RPort, JAM2 );
  759.     wheight = ( w->Height - w->BorderTop - w->BorderBottom - 2 ) /
  760.         w->RPort->TxHeight;
  761.  
  762.     /* Skip any initial response to a previous line */
  763.     if( cw->type == NHW_MESSAGE )
  764.     {
  765.     if( cw->data[start] && cw->data[ start ][1] == 1 )
  766.         ++start;
  767.     }
  768.  
  769.     for( idx = i = start; idx < start + wheight; i++ )
  770.     {
  771.         if( i >= cw->maxrow )
  772.         {
  773.         amii_curs( win, 1, idx - start );
  774.         amii_cl_end( cw, 0 );
  775.         ++idx;
  776.         continue;
  777.         }
  778.  
  779.     /* Any character with an highlighted attribute go
  780.      * onto the end of the current line in the message window.
  781.      */
  782.     if( cw->type == NHW_MESSAGE )
  783.         SetAPen( w->RPort, cw->data[i][1] ? C_RED : C_WHITE );
  784.  
  785.     if( cw->type != NHW_MESSAGE || cw->data[i][1] == 0 )
  786.         amii_curs( win, 1, idx - start );
  787.  
  788.     if( where == i )
  789.     {
  790.         if( col != 1 )
  791.         {
  792.         SetAPen( w->RPort, C_BLUE );
  793.         SetBPen( w->RPort, C_WHITE );
  794.         col = 1;
  795.         }
  796.     }
  797.     else if( col != 2 )
  798.     {
  799.         SetAPen( w->RPort, C_WHITE );
  800.         SetBPen( w->RPort, C_BLACK );
  801.         col = 2;
  802.     }
  803.  
  804.     /* Next line out, truncate if too long */
  805.  
  806.     len = 0;
  807.     t = cw->data[ i ] + SOFF;
  808.     len = strlen( t );
  809.     if( len > cw->cols )
  810.         len = cw->cols;
  811.     Text( w->RPort, t, len );
  812.  
  813.     if( cw->type != NHW_MESSAGE || cw->data[i][1] == 0 )
  814.     {
  815.         amii_cl_end( cw, len );
  816.         ++idx;
  817.     }
  818.     }
  819.     return;
  820. }
  821.  
  822. void SetPropInfo( win, gad, vis, total, top )
  823.     register struct Window *win;
  824.     register struct Gadget *gad;
  825.     register long vis, total, top;
  826. {
  827.     long mflags;
  828.     register long hidden;
  829.     register int body, pot;
  830.  
  831.     hidden = max( total-vis, 0 );
  832.  
  833.     /* Force the last section to be just to the bottom */
  834.  
  835.     if( top > hidden )
  836.     top = hidden;
  837.  
  838.     /* Scale the body position. */
  839.     /* 2 lines overlap */
  840.  
  841.     if( hidden > 0 && total != 0 )
  842.     body = (ULONG) ((vis - 2) * MAXBODY) / (total - 2);
  843.     else
  844.     body = MAXBODY;
  845.  
  846.     if( hidden > 0 )
  847.     pot = (ULONG) (top * MAXPOT) / hidden;
  848.     else
  849.     pot = 0;
  850.  
  851.     mflags = AUTOKNOB|FREEVERT;
  852. #ifdef  INTUI_NEW_LOOK
  853.     if( IntuitionBase->LibNode.lib_Version >= 37 )
  854.     {
  855.     mflags |= PROPNEWLOOK;
  856.     }
  857. #endif
  858.  
  859.     NewModifyProp( gad, win, NULL,
  860.                 mflags, 0, pot, MAXBODY, body, 1 );
  861. }
  862.